﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SharingCenter.Web.Classes
{
    using enums;
    public class PostOperations
    {
        public static List<ThreadWithMainPost> GetThreadInGroups(Guid userId, int takeCount)
        {
            string q = string.Format("EXEC GetThreadsByUserGroups '{0}', {1}", userId.ToString(), takeCount);
            using (scDataContext cxt = new scDataContext())
            {
                return cxt.ExecuteQuery<ThreadWithMainPost>(q).ToList();
            }
            
        }

        public static Sc_PostThread CreateThread(Guid creatorUserId, Guid category, PostType type, string threadIcon, bool submit)
        {
            Guid newId = Guid.NewGuid();
            Sc_PostThread t = new Sc_PostThread();
            t.CreateDate = DateTime.Now;
            t.IsRecommended = false;
            t.CategoryId = category;
            //t.ThreadId = newId;
            t.ThreadType = type;
            t.TotalPosts = 0;
            t.ViewCount = 0;
            t.CreatorUserId = creatorUserId;
            t.LastUpdate = DateTime.Now;
            t.ThreadIcon = threadIcon;

            scDataContext.Instance.Sc_PostThreads.InsertOnSubmit(t);
            scDataContext.Instance.SubmitChanges();
            return t;
        }

        public static Sc_PostCategory GetCategory(Guid cateId)
        {
            try
            {
                return scDataContext.Instance.Sc_PostCategories.Single(d => d.PostCategoryId == cateId);
                //using (scDataContext cxt = new scDataContext())
                //{
                //    return cxt.Sc_PostCategories.Single(d => d.PostCategoryId == cateId);
                //}
            }
            catch
            {
                return null;
            }
        }

        public static Sc_Post CreatePost(Guid threadId, Guid creatorUserId, string title, string content, PostType type, string signature, bool submit)
        {
            Sc_Post p = new Sc_Post();
            p.PostId = Guid.NewGuid();
            p.ThreadId = threadId;
            p.PostDate = DateTime.Now;
            p.PostTitle = title;
            p.PostContent = content;
            p.PostSignature = signature;
            p.PostUserId = creatorUserId;
            p.LastUpdateDate = DateTime.Now;
            p.PostType = type;
            p.PostIndex = 0;
            p.IsMainPost = false;
            p.IsApproved = true;
            p.IsDeleted = false;

            
            scDataContext.Instance.Sc_Posts.InsertOnSubmit(p);
            if (submit)
            {
                scDataContext.Instance.SubmitChanges();
            }
            return p;
        }

        public static void SetRecommendedThread(Guid threadId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                Sc_PostThread p = cxt.Sc_PostThreads.Single(d => d.ThreadId == threadId);
                p.IsRecommended = !p.IsRecommended;
                cxt.SubmitChanges();
            }
        }

        public static void UpdateViewCount(Guid threadId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                Sc_PostThread p = cxt.Sc_PostThreads.Single(d => d.ThreadId == threadId);
                p.ViewCount++;
                cxt.SubmitChanges();
            }
        }

        public static Sc_Post GetMainPostInThread(Guid threadId)
        {
            //return GetPostByPostId(GetThreadByThreadId(threadId).MainPostId);

            var q = from p in scDataContext.Instance.Sc_Posts
                    where p.IsMainPost && p.ThreadId == threadId
                    select p;

            try
            {
                return q.First();
            }
            catch
            {
                return null;
            }
        }

        public static Sc_PostThread GetThreadByThreadId(Guid threadId)
        {
            try
            {
                //using (scDataContext cxt = new scDataContext())
                //{
                //    return cxt.Sc_PostThreads.Single(d => d.ThreadId == threadId);
                //}
                return scDataContext.Instance.Sc_PostThreads.Single(d => d.ThreadId == threadId);
            }
            catch { return null; }
        }

        public static List<ThreadWithMainPost> GetUserThreads(Guid userId, int takeCount)
        {
            using (scDataContext cxt = new scDataContext())
            {
                if (takeCount > 0)
                {
                    var q = (from t in cxt.ThreadWithMainPosts
                             where t.CreatorUserId == userId
                             orderby t.CreateDate descending
                             select t).Take(takeCount);
                    return q.ToList();
                }
                else
                {
                    var q = from t in cxt.ThreadWithMainPosts
                            where t.CreatorUserId == userId
                            orderby t.CreateDate descending
                            select t;
                    return q.ToList();
                }
            }
        }

        public static List<ThreadWithMainPost> GetUserThreads(Guid userId, int takeCount, EntityType type)
        {
            if (takeCount > 0)
            {
                var q = (from t in scDataContext.Instance.ThreadWithMainPosts
                         where t.CreatorUserId == userId && t.ContextType == type && t.Enabled
                         orderby t.CreateDate descending
                         select t).Take(takeCount);
                return q.ToList();
            }
            else
            {
                var q = from t in scDataContext.Instance.ThreadWithMainPosts
                        where t.CreatorUserId == userId && t.ContextType == type && t.Enabled
                        orderby t.CreateDate descending
                        select t;
                return q.ToList();
            }

        }

        public static Sc_Post GetPostByPostId(Guid? postId)
        {
            if (postId != null)
            {
                try
                {
                    return scDataContext.Instance.Sc_Posts.Single(d => d.PostId == postId);
                }
                catch { return null; }
            }
            else
            {
                return null;
            }
        }

        public static List<ThreadWithMainPost> GetThreadListByReplyUserId(Guid userId)
        {
            ////var q = from p in scDataContext.Instance.Sc_Posts
            ////        where p.PostUserId == userId
            ////        join t in scDataContext.Instance.Sc_PostThreads
            ////        on p.ThreadId equals t.ThreadId
            ////        select t;

            var e = from t in scDataContext.Instance.ThreadWithMainPosts
                    join p in scDataContext.Instance.Sc_Posts
                    on t.ThreadId equals p.ThreadId
                    where p.PostUserId == userId
                    select t;
            return e.Distinct().ToList();
        }

        public static List<ThreadWithMainPost> GetThreadListByReplyUserId(Guid userId, Guid categoryId)
        {
            ////var q = from p in scDataContext.Instance.Sc_Posts
            ////        where p.PostUserId == userId
            ////        join t in scDataContext.Instance.Sc_PostThreads
            ////        on p.ThreadId equals t.ThreadId
            ////        select t;

            var e = from t in scDataContext.Instance.ThreadWithMainPosts
                    join p in scDataContext.Instance.Sc_Posts
                    on t.ThreadId equals p.ThreadId
                    where p.PostUserId == userId && t.CategoryId == categoryId
                    select t;
            return e.Distinct().ToList();
        }

        public static void MarkPostAsDeleted(Guid postId)
        {
            Sc_Post item = GetPostByPostId(postId);
            if (item != null)
            {
                item.IsDeleted = true;
                scDataContext.Instance.SubmitChanges();
            }
        }

        public static List<ThreadWithMainPost> GetHotThread(int takeCount)
        {
            var q = (from t in scDataContext.Instance.ThreadWithMainPosts
                     where t.Enabled && t.ContextId == null && (
                     t.ViewCount >= Convert.ToInt32(SiteConfig.ReadSetting(SiteConfigSection.Post, "HotThreadByReadCount"))
                     || t.TotalPosts >= Convert.ToInt32(SiteConfig.ReadSetting(SiteConfigSection.Post, "HotThreadByReplyCount")) - 1
                     || Convert.ToBoolean(t.IsHot))
                     orderby t.IsHot descending, t.TotalPosts descending, t.ViewCount descending
                     select t
                         ).Take(takeCount);
            return q.ToList();
                    
        }

        public static void SetCancelThreadHot(Guid threadId)
        {
            Sc_PostThread t = GetThreadByThreadId(threadId);
            if (t != null)
            {
                t.IsHot = !t.IsHot;
                scDataContext.Instance.SubmitChanges();
                scDataContext.Instance.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, t);
            }
            
        }

        public static void DeleteThread(Guid threadId)
        {
            scDataContext.Instance.DeleteThread(threadId);
        }
    }
}
